package com.css.apps.base.user.service;

import com.alibaba.fastjson.JSON;
import com.css.apps.base.common.Constants;
import com.css.apps.base.common.util.OrikaUtil;
import com.css.apps.base.log.model.LogConstant;
import com.css.apps.base.log.model.LogPart;
import com.css.apps.base.org.model.SOrg;
import com.css.apps.base.org.model.SUserOrg;
import com.css.apps.base.security.model.SecurityParam;
import com.css.apps.base.security.service.SecurityService;
import com.css.apps.base.user.model.SUser;
import com.css.apps.base.user.po.*;
import com.css.core.configuration.Environment;
import com.css.db.query.QueryCache;
import com.css.db.query.TransactionCache;
import com.css.ids.server.service.IdsService;
import com.css.util.*;
import com.css.webbase.WebBaseUtil;
import org.apache.commons.beanutils.BeanUtils;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * create by Mr.X
 * 2021.07.04
 */
public class UserService {

    private String result;
    private String operFlag = "add";
    private final String PACKAGE_PATH = "com.css.apps.base.user.po."; // po/vo 的包路径

    /**
     * 前置输入安全检查  不通过返回false
     * @param lableId
     * @param userInfoPageVo
     * @return
     */
    public boolean perCheck(String lableId, UserInfoPageVo userInfoPageVo,String operFlag){
        switch (lableId){
            case "userInfo":
            {
                //必填字段检查
                if ( StringHelper.isEmpty(userInfoPageVo.getUserInfoVo().getRealName()) || StringHelper.isEmpty(userInfoPageVo.getOrgIds())) {
                    this.result = Ajax.JSONResult(Environment.RESULT_CODE_ERROR, Messages.getString("systemMsg.fieldEmpty"));
                    return false;
                }
                // 添加情况不能出现相同的UUID
                if("add".equals(operFlag)){
                    SUser user = QueryCache.get(SUser.class, userInfoPageVo.getUserInfoVo().getUuid());
                    if (user != null) {
                        this.result = Ajax.JSONResult(Environment.RESULT_CODE_ERROR, Messages.getString("sysmgrMsg.idExist"));
                        return false;
                    }
                }
                // 不能出现相同的登录名（除了本人未修改直接保存）
                String newLoginName = userInfoPageVo.getUserInfoVo().getLoginName();
                if(StringHelper.isNotEmpty(newLoginName)){
                    if("add".equals(operFlag)){
                        List<String> l = new QueryCache("select a.uuid from SUser a where a.loginName =:loginName").setParameter("loginName",newLoginName).list();
                        if(ListUtil.isLstNotEmpty(l)){
                            this.result = Ajax.JSONResult(Environment.RESULT_CODE_ERROR, Messages.getString("sysmgrMsg.loginnameExsit",new String[] { newLoginName }));
                            return false;
                        }
                    }else{
                        String oldLoginName = QueryCache.get(SUser.class,userInfoPageVo.getUserInfoVo().getUuid()).getLoginName();
                        if(!newLoginName.equals(oldLoginName)){
                            List<String> l = new QueryCache("select a.uuid from SUser a where a.loginName =:loginName").setParameter("loginName",newLoginName).list();
                            if(ListUtil.isLstNotEmpty(l)){
                                this.result = Ajax.JSONResult(Environment.RESULT_CODE_ERROR, Messages.getString("sysmgrMsg.loginnameExsit",new String[] { newLoginName }));
                                return false;
                            }
                        }
                    }
                }
                break;
            }
            //TODO 后续可依据实际需求对其他lable前置检查进行扩展
        }
        return true;
    }

    /**
     * 前置输入安全检查  不通过返回false
     * @param lableId
     * @param userInfoDialogVo
     * @return
     */
    public boolean perCheck(String lableId, UserInfoDialogVo userInfoDialogVo,String operFlag){
        switch (lableId){
            case "userInfo":
            {
                //必填字段检查
                if ( StringHelper.isEmpty(userInfoDialogVo.getUserInfoVo().getRealName()) || StringHelper.isEmpty(userInfoDialogVo.getOrgIds())) {
                    this.result = Ajax.JSONResult(Environment.RESULT_CODE_ERROR, Messages.getString("systemMsg.fieldEmpty"));
                    return false;
                }
                if("add".equals(operFlag)){
                    // 不能出现相同的UUID
                    SUser user = QueryCache.get(SUser.class, userInfoDialogVo.getUserInfoVo().getUuid());
                    if (user != null) {
                        this.result = Ajax.JSONResult(Environment.RESULT_CODE_SUCCESS, Messages.getString("sysmgrMsg.idExist"));
                        return false;
                    }
                }
                // 不能出现相同的登录名（除了本人未修改直接保存）
                String newLoginName = userInfoDialogVo.getUserInfoVo().getLoginName();
                if(StringHelper.isNotEmpty(newLoginName)){
                    if("add".equals(operFlag)){
                        List<String> l = new QueryCache("select a.uuid from SUser a where a.loginName =:loginName").setParameter("loginName",newLoginName).list();
                        if(ListUtil.isLstNotEmpty(l)){
                            this.result = Ajax.JSONResult(Environment.RESULT_CODE_ERROR, Messages.getString("sysmgrMsg.loginnameExsit",new String[] { newLoginName }));
                            return false;
                        }
                    }else{
                        String oldLoginName = QueryCache.get(SUser.class,userInfoDialogVo.getUserInfoVo().getUuid()).getLoginName();
                        if(!newLoginName.equals(oldLoginName)){
                            List<String> l = new QueryCache("select a.uuid from SUser a where a.loginName =:loginName").setParameter("loginName",newLoginName).list();
                            if(ListUtil.isLstNotEmpty(l)){
                                this.result = Ajax.JSONResult(Environment.RESULT_CODE_ERROR, Messages.getString("sysmgrMsg.loginnameExsit",new String[] { newLoginName }));
                                return false;
                            }
                        }
                    }
                }
                break;
            }
            //TODO 后续可依据实际需求对其他lable前置检查进行扩展
        }
        return true;
    }

    /**
     * 新增用户信息
     * @param GENERATE_UUID
     * @param lableId
     * @param userInfoDialogVo
     * @param tx
     * @throws Exception
     */
    public TransactionCache saveDB(String GENERATE_UUID, String lableId, UserInfoDialogVo userInfoDialogVo, TransactionCache tx) throws  Exception{
        return  saveDBByReflex(GENERATE_UUID,lableId,userInfoDialogVo,tx);
    }

    /**
     * 新增用户信息
     * @param GENERATE_UUID
     * @param lableId
     * @param userInfoPageVo
     * @param tx
     * @throws Exception
     */
    public TransactionCache saveDB(String GENERATE_UUID, String lableId, UserInfoPageVo userInfoPageVo, TransactionCache tx) throws  Exception{
        return saveDBByReflex(GENERATE_UUID,lableId,userInfoPageVo,tx);
    }

    /**
     * 修改用户信息
     * @param lableId
     * @param userId
     * @param userInfoPageVo
     * @param tx
     * @throws Exception
     */
    public TransactionCache updateDB(String lableId, String userId,UserInfoPageVo userInfoPageVo, TransactionCache tx) throws Exception{
        return updateDBByReflex(lableId,userId,userInfoPageVo,tx);
    }

    /**
     * 修改用户信息
     * @param lableId
     * @param uuid
     * @param userInfoDialogVo
     * @param tx
     * @throws Exception
     */
    public TransactionCache updateDB(String lableId, String uuid,UserInfoDialogVo userInfoDialogVo, TransactionCache tx) throws Exception{
        return  updateDBByReflex(lableId,uuid,userInfoDialogVo,tx);
    }

    /**
     * 删除用户信息
     * @param lableId
     * @param ids
     * @param tx
     */
    public void delDB(String lableId, String ids, TransactionCache tx) throws Exception{
        delDBByReflex(lableId, ids, tx);
    }

    /**
     * 删除用户
     * @param idsList
     * @param tx
     * @throws Exception
     */
    public void delUser(List<String> idsList, TransactionCache tx) throws Exception{
        String[] userRelateTables = {"SUserOrg","SUserRole","SUserPost","UserDutyPo","UserRankPo","UserSkillPo",
                "UserEducationPo","UserRewardAndPunishPo","UserExaminePo","UserFamilyPo","UserOtherPo"};
        List<String> sqlList = new ArrayList<>();
        for (String userRelateTable : userRelateTables) {
            String sqlStr = "delete from "+ userRelateTable +" a where a.userId in (:userId)";
            sqlList.add(sqlStr);
        }
        Map<String, Object> params = new HashMap<>();
        params.put("userId", idsList);
        //逻辑删除用户
        List<SUser> userItemList = QueryCache.idToObj(SUser.class,idsList);
        for (SUser userItem : userItemList) {
            userItem.setDelFlag("1");
            userItem.setEditDate(new Date());
            userItem.setLoginName(userItem.getLoginName()+"_del"+new Date());
        }
        tx = new TransactionCache();
        tx.update(userItemList);
        //物理用户相关数据信息
        for (String sqlStr : sqlList) {
            tx.executeUpdate(sqlStr, params);
        }
        tx.commit();
    }

    /**
     * 删除用户信息
     * @param lableId
     * @param ids
     * @param tx
     */
    private <poClazz> void delDBByReflex(String lableId, String ids, TransactionCache tx) throws Exception{
        //构建vo po 模板
        String PoPackagePath = PACKAGE_PATH + changeFirstChar2UpperCase(lableId) + "Po";
        Class poClazz = Class.forName(PoPackagePath);
        List<poClazz> poList = QueryCache.idToObj(poClazz,StringHelper.strToList(ids));
        tx = new TransactionCache();
        tx.delete(poList);
        tx.commit();
    }

    /**
     * 创建VO对象 （全览用户信息）
     * @param userId
     * @return
     */
    public UserInfoPageVo createAllUserInfoPageVo(String userId) throws Exception{
        return  createAllUserInfoPageVoByReflex(userId);
    }

    /**
     * 创建VO对象 （lable列表页）
     * @param lableId
     * @param userId
     * @return
     */
    public UserInfoPageVo createUserInfoPageVo(String lableId, String userId) throws Exception{
        return  createUserInfoPageVoByReflex(lableId,userId);
    }

    /**
     * 创建vo对象 （lable页内弹框）
     * @param lableId
     * @param uuid
     * @return
     * @throws Exception
     */
    public UserInfoDialogVo createUserInfoDialogVo(String lableId, String uuid) throws Exception {
        return  createUserInfoDialogVoByReflex(lableId,uuid);
    }

    /**
     * 反射创建Vo
     * @param lableId
     * @param uuid
     * @param <poClazz>
     * @param <voClazz>
     * @return
     * @throws Exception
     */
    private <poClazz, voClazz> UserInfoDialogVo createUserInfoDialogVoByReflex(String lableId , String uuid) throws Exception{
        UserInfoDialogVo userInfoDialogVo = new UserInfoDialogVo();
        OrikaUtil orikaUtil = new OrikaUtil();
        {
            //构建vo po 模板
            String VoPackagePath = PACKAGE_PATH + changeFirstChar2UpperCase(lableId) + "Vo";
            String PoPackagePath = PACKAGE_PATH + changeFirstChar2UpperCase(lableId) + "Po";
            Class voClazz = Class.forName(VoPackagePath);
            Class poClazz = Class.forName(PoPackagePath);
            //获取voList
            poClazz po = (poClazz) QueryCache.get(poClazz,uuid);
            voClazz vo = (voClazz) orikaUtil.convert(voClazz,po);
            //将vo注入userInfoDialogVo
            try {
                String setterMethods = "set" + changeFirstChar2UpperCase(lableId) + "Vo";
                Method method = (Method) userInfoDialogVo.getClass().getDeclaredMethod(setterMethods,voClazz);
                method.setAccessible(true);
                method.invoke(userInfoDialogVo,vo);
            }catch (NoSuchMethodException e) {
                e.printStackTrace();
            }catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
            this.operFlag = "upd";
        }
        return userInfoDialogVo;
    }

    /**
     * 反射创建Vo
     * @param lableId
     * @param userId
     * @param <poClazz>
     * @param <voClazz>
     * @return
     * @throws Exception
     */
    private <poClazz, voClazz> UserInfoPageVo createUserInfoPageVoByReflex(String lableId , String userId) throws Exception{
        UserInfoPageVo userInfoPageVo = new UserInfoPageVo();
        OrikaUtil orikaUtil = new OrikaUtil();
        if("userInfo".equals(lableId)){
            //注入人员基本信息
            SUser sUser = QueryCache.get(SUser.class,userId);
            if(sUser!=null){
                UserInfoVo userInfoVo = orikaUtil.convert(UserInfoVo.class,sUser);
                userInfoPageVo.setUserInfoVo(userInfoVo);
                this.operFlag = "upd";
            }
            //注入家庭信息
            List<UserFamilyPo> familyList = new QueryCache("from UserFamilyPo a where a.userId =:userId")
                    .setParameter("userId",userId).list();
            if(ListUtil.isLstNotEmpty(familyList)){
                List<UserFamilyVo> userFamilyVoList = orikaUtil.convertList(UserFamilyVo.class,familyList);
                userInfoPageVo.setUserFamilyVoList(userFamilyVoList);
            }
        }else{
            //构建vo po 模板
            String VoPackagePath = PACKAGE_PATH + changeFirstChar2UpperCase(lableId) + "Vo";
            String PoPackagePath = PACKAGE_PATH + changeFirstChar2UpperCase(lableId) + "Po";
            Class voClazz = Class.forName(VoPackagePath);
            Class poClazz = Class.forName(PoPackagePath);

            String querySql= "from "+ changeFirstChar2UpperCase(lableId) + "Po " + "a where a.userId =:userId";
            List<poClazz> poList = new QueryCache(querySql).setParameter("userId",userId).list();
            if(!ListUtil.isLstEmpty(poList)){
                List<voClazz> voList = (List<voClazz>) orikaUtil.convertList(voClazz,poList);
                //注入vo对象
                try {
                    String[] lableIds = {"userOther"};
                    if(Arrays.asList(lableIds).contains(lableId)){
                        String setterMethods = "set" + changeFirstChar2UpperCase(lableId) + "Vo";
                        Method method = (Method) userInfoPageVo.getClass().getDeclaredMethod(setterMethods,voClazz);
                        method.setAccessible(true);
                        method.invoke(userInfoPageVo,voList.get(0));
                    }else{
                        String setterMethods = "set" + changeFirstChar2UpperCase(lableId) + "VoList";
                        Method method = (Method) userInfoPageVo.getClass().getDeclaredMethod(setterMethods,List.class);
                        method.setAccessible(true);
                        method.invoke(userInfoPageVo,voList);
                    }
                }catch (NoSuchMethodException e) {
                    e.printStackTrace();
                }catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
                this.operFlag = "upd";
            }
        }
        return userInfoPageVo;
    }

    /**
     * 反射创建Vo（全览用户信息）
     * @param userId
     * @param <poClazz>
     * @param <voClazz>
     * @return
     * @throws Exception
     */
    private <poClazz, voClazz> UserInfoPageVo createAllUserInfoPageVoByReflex(String userId) throws Exception{
        UserInfoPageVo userInfoPageVo = new UserInfoPageVo();
        OrikaUtil orikaUtil = new OrikaUtil();
        SUser sUser = QueryCache.get(SUser.class,userId);
        if(sUser!=null){
            UserInfoVo userInfoVo = orikaUtil.convert(UserInfoVo.class,sUser);
            userInfoPageVo.setUserInfoVo(userInfoVo);
        }
        String[] userRelateTables = {"UserDutyPo","UserRankPo","UserSkillPo",
                "UserEducationPo","UserRewardAndPunishPo","UserExaminePo","UserFamilyPo","UserOtherPo"};
        List<String> sqlList = new ArrayList<>();
        for (String userRelateTable : userRelateTables) {
            try {
                String voName = poName2voName(userRelateTable);
                String querySql = "from "+ userRelateTable +" a where a.userId =:userId";
                List<poClazz> poList = new QueryCache(querySql).setParameter("userId",userId).list();
                if(!ListUtil.isLstEmpty(poList)){
                    Class voClazz = Class.forName(PACKAGE_PATH + voName+"Vo");
                    List<voClazz> voList = (List<voClazz>) orikaUtil.convertList(voClazz,poList);
                    //注入vo对象
                    try {
                        String[] pos = {"UserDutyPo"};
                        if(Arrays.asList(pos).contains(userRelateTable)){
                            String setterMethods = "set" + voName + "Vo";
                            Method method = (Method) userInfoPageVo.getClass().getDeclaredMethod(setterMethods,voClazz);
                            method.setAccessible(true);
                            method.invoke(userInfoPageVo,voList.get(0));
                        }else{
                            String setterMethods = "set" + voName + "VoList";
                            Method method = (Method) userInfoPageVo.getClass().getDeclaredMethod(setterMethods,List.class);
                            method.setAccessible(true);
                            method.invoke(userInfoPageVo,voList);
                        }
                    }catch (NoSuchMethodException e) {
                        e.printStackTrace();
                    }catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }
                }
            }catch (Exception e){
                e.printStackTrace();
                continue;
            }
        }
        return userInfoPageVo;
    }

    /**
     * 保存单一对象 (弹框保存)
     * @param GENERATE_UUID
     * @param lableId
     * @param tx
     * @param userInfoDialogVo
     * @param <poClazz>
     * @param <voClazz>
     */
    private  <poClazz, voClazz> TransactionCache saveDBByReflex(String GENERATE_UUID, String lableId, UserInfoDialogVo userInfoDialogVo, TransactionCache tx) throws  Exception{
        OrikaUtil orikaUtil = new OrikaUtil();
        //构建vo po 模板
        String VoPackagePath = PACKAGE_PATH + changeFirstChar2UpperCase(lableId) + "Vo";
        String PoPackagePath = PACKAGE_PATH + changeFirstChar2UpperCase(lableId) + "Po";
        Class voClazz = Class.forName(VoPackagePath);
        Class poClazz = Class.forName(PoPackagePath);
        //获取VO
        voClazz vo = null;
        try {
            String getterMethods = "get" + changeFirstChar2UpperCase(lableId) + "Vo";
            Method method = (Method) userInfoDialogVo.getClass().getDeclaredMethod(getterMethods);
            method.setAccessible(true); //设置强制访问，可执行某类的private私有方法。
            vo = (voClazz) method.invoke(userInfoDialogVo);
        }catch (NoSuchMethodException e) {
            e.printStackTrace();
        }catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        //获取PO
        poClazz po = (poClazz) orikaUtil.convert(poClazz,vo);
        //初始化uuid，laste_modify_time
        try {
            Method setUuidmethod = (Method) poClazz.getDeclaredMethod("setUuid",String.class);
            Method setLastModifyTimeMethod = (Method) poClazz.getDeclaredMethod("setLastmodifytime",Date.class);
            setUuidmethod.setAccessible(true);
            setLastModifyTimeMethod.setAccessible(true);
            setUuidmethod.invoke(po,GENERATE_UUID);
            setLastModifyTimeMethod.invoke(po,new Date());
        }catch (NoSuchMethodException e) {
            e.printStackTrace();
        }catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        tx = new TransactionCache();
        tx.save(po);
        tx.commit();
        return tx;
    }

    /**
     * 保存单一对象  （lable页保存）
     * @param GENERATE_UUID
     * @param lableId
     * @param tx
     * @param userInfoPageVo
     * @param <poClazz>
     * @param <voClazz>
     */
    private  <poClazz, voClazz> TransactionCache saveDBByReflex(String GENERATE_UUID, String lableId, UserInfoPageVo userInfoPageVo, TransactionCache tx) throws  Exception{
        OrikaUtil orikaUtil = new OrikaUtil();
        if("userInfo".equals(lableId)){
            //创建PO
            SUser item  = orikaUtil.convert(SUser.class,userInfoPageVo.getUserInfoVo());
            item.setUuid(GENERATE_UUID);
            // 将第一个部门id加入SUser表中的orgId字段
            List<String> orgIdList = StringHelper.strToList(userInfoPageVo.getOrgIds());
            item.setOrgId(orgIdList.get(0));
            item.setOpenFlag(Constants.YES);
            item.setDelFlag(Environment.UN_DELETE_STATE);
            item.setIssueDate(new Date());
            item.setIssueId(WebBaseUtil.getCurrentUser().getUserId());
            item.setIssueName(WebBaseUtil.getCurrentUser().getRealName());
            item.setEditDate(new Date());
            item.setTotalLoginCount(0);
            item.setFailedLoginCount(0);
            item.setActiveStatus("3");
            item.setFailedLoginCount(0);
            item.setLastmodifytime(new Date());
            //如果没在系统中进行配置则给与默认密码。
            String password = SecurityService.getParamValue(SecurityParam.INIT_PASSWORD);
            if (StringHelper.isEmpty(password)) {
                item.setPassword(Md5Util.MD5Encode(Md5Util.MD5Encode("123456")));
            } else {
                item.setPassword(Md5Util.MD5Encode(Md5Util.MD5Encode(password)));
            }
            // 添加现有部门-用户关联
            List<SUserOrg> sUserOrgList = new ArrayList<>();
            for (String orgId : orgIdList) {
                SUserOrg userorg = new SUserOrg();
                userorg.setOrgId(getCorp(orgId).getUuid());
                userorg.setDeptId(orgId.trim());
                userorg.setUserId(item.getUuid());
                sUserOrgList.add(userorg);
                item.getOrgList().add(orgId.trim());
            }
            //解析家庭成员信息
            List<UserFamilyPo> UserFamilyPoList = new ArrayList<>();
            if(StringHelper.isNotEmpty(userInfoPageVo.getUserInfoVo().getFamilyJsonStr())){
                UserFamilyPoList = JSON.parseArray(userInfoPageVo.getUserInfoVo().getFamilyJsonStr(), UserFamilyPo.class);
                for (UserFamilyPo userFamilyPo : UserFamilyPoList) {
                    userFamilyPo.setUuid(UuidUtil.getUuid());
                    userFamilyPo.setUserId(GENERATE_UUID);
                }
            }
            tx = new TransactionCache();
            tx.save(sUserOrgList);
            tx.save(item);
            if(ListUtil.isLstNotEmpty(UserFamilyPoList)){
                tx.save(UserFamilyPoList);
            }
            tx.commit();
            recordLog(GENERATE_UUID,LogConstant.LOG_TYPE_ADD);
        }else{
            //构建vo po 模板
            String VoPackagePath = PACKAGE_PATH + changeFirstChar2UpperCase(lableId) + "Vo";
            String PoPackagePath = PACKAGE_PATH + changeFirstChar2UpperCase(lableId) + "Po";
            Class voClazz = Class.forName(VoPackagePath);
            Class poClazz = Class.forName(PoPackagePath);
            //获取VO
            voClazz vo = null;
            try {
                String getterMethods = "get" + changeFirstChar2UpperCase(lableId) + "Vo";
                Method method = (Method) userInfoPageVo.getClass().getDeclaredMethod(getterMethods);
                method.setAccessible(true); //设置强制访问，可执行某类的private私有方法。
                vo = (voClazz) method.invoke(userInfoPageVo);
            }catch (NoSuchMethodException e) {
                e.printStackTrace();
            }catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
            //获取PO
            poClazz po = (poClazz) orikaUtil.convert(poClazz,vo);
            //初始化uuid
            try {
                Method setUuidmethod = (Method) poClazz.getDeclaredMethod("setUuid",String.class);
                Method setLastModifyTimeMethod = (Method) poClazz.getDeclaredMethod("setLastmodifytime",Date.class);
                setUuidmethod.setAccessible(true);
                setLastModifyTimeMethod.setAccessible(true);
                setUuidmethod.invoke(po,GENERATE_UUID);
                setLastModifyTimeMethod.invoke(po,new Date());
            }catch (NoSuchMethodException e) {
                e.printStackTrace();
            }catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
            tx = new TransactionCache();
            tx.save(po);
            tx.commit();
        }
        return tx;
    }

    /**
     * 修改单一对象 （修改lable）
     * @param lableId
     * @param userId
     * @param userInfoPageVo
     * @param tx
     */
    private <voClazz, poClazz> TransactionCache updateDBByReflex(String lableId, String userId, UserInfoPageVo userInfoPageVo, TransactionCache tx) throws  Exception{
        //修改个人信息主表特殊处理，其他信息表全部通过反射动态创建。
        if("userInfo".equals(lableId)){
            // 将第一个部门id加入SUser表中的orgId字段
            List<String> orgIdList = StringHelper.strToList(userInfoPageVo.getOrgIds());
            SUser userItem = QueryCache.get(SUser.class,userId);
            BeanUtils.copyProperties(userItem,userInfoPageVo.getUserInfoVo());
            userItem.setUuid(userId);
            userItem.setOrgId(orgIdList.get(0));
            userItem.setLastmodifytime(new Date());
            // 先将原有部门-用户关联纪录删除，再添加
            userItem.getOrgList().removeAll();
            List<SUserOrg> sUserOrgList = new ArrayList<>();
            for (String orgId : orgIdList) {
                SUserOrg userorg = new SUserOrg();
                userorg.setOrgId(getCorp(orgId).getUuid());
                userorg.setDeptId(orgId.trim());
                userorg.setUserId(userItem.getUuid());
                sUserOrgList.add(userorg);
                userItem.getOrgList().add(orgId.trim());
            }
            //更新家庭成员信息（删除重新添加）
            List<UserFamilyPo> UserFamilyPoList = new ArrayList<>();
            if(StringHelper.isNotEmpty(userInfoPageVo.getUserInfoVo().getFamilyJsonStr())){
                UserFamilyPoList = JSON.parseArray(userInfoPageVo.getUserInfoVo().getFamilyJsonStr(), UserFamilyPo.class);
                for (UserFamilyPo userFamilyPo : UserFamilyPoList) {
                    userFamilyPo.setUuid(UuidUtil.getUuid());
                    userFamilyPo.setUserId(userId);
                }
            }
            Map<String, Object> params = new HashMap<>();
            params.put("userId", userId);
            tx = new TransactionCache();
            tx.executeUpdate("delete from SUserOrg a where a.userId=:userId", params);
            tx.save(sUserOrgList);
            if(StringHelper.isNotEmpty(userInfoPageVo.getUserInfoVo().getFamilyJsonStr())){
                tx.executeUpdate("delete from UserFamilyPo a where a.userId=:userId", params);
                if(ListUtil.isLstNotEmpty(UserFamilyPoList)){
                    tx.save(UserFamilyPoList);
                }
            }
            tx.update(userItem);
            tx.commit();
        }else{
            //构建vo po 模板
            String VoPackagePath = PACKAGE_PATH + changeFirstChar2UpperCase(lableId) + "Vo";
            String PoPackagePath = PACKAGE_PATH + changeFirstChar2UpperCase(lableId) + "Po";
            Class voClazz = Class.forName(VoPackagePath);
            Class poClazz = Class.forName(PoPackagePath);
            //获取uuid
            String uuid = "";
            voClazz vo = null;
            try {
                String getterMethods = "get" + changeFirstChar2UpperCase(lableId) + "Vo";
                Method method = (Method) userInfoPageVo.getClass().getDeclaredMethod(getterMethods);
                method.setAccessible(true);
                vo = (voClazz) method.invoke(userInfoPageVo);
                Method getUuidmethod = (Method) voClazz.getDeclaredMethod("getUuid");
                getUuidmethod.setAccessible(true);
                uuid = (String) getUuidmethod.invoke(vo);
            }catch (NoSuchMethodException e) {
                e.printStackTrace();
            }catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
            //获取po
            poClazz po = (poClazz) QueryCache.get(poClazz,uuid);
            BeanUtils.copyProperties(po,vo);
            //更新po最新变更时间
            Method setLastModifyTimeMethod = (Method) poClazz.getDeclaredMethod("setLastmodifytime",Date.class);
            setLastModifyTimeMethod.setAccessible(true);
            setLastModifyTimeMethod.invoke(po,new Date());
            tx = new TransactionCache();
            tx.update(po);
            tx.commit();
        }
        return tx;
    }

    /**
     * 修改单一对象 (修改弹框)
     * @param lableId
     * @param uuid
     * @param userInfoDialogVo
     * @param tx
     */
    private <voClazz, poClazz> TransactionCache updateDBByReflex(String lableId, String uuid, UserInfoDialogVo userInfoDialogVo, TransactionCache tx) throws  Exception{
        //构建vo po 模板
        String VoPackagePath = PACKAGE_PATH + changeFirstChar2UpperCase(lableId) + "Vo";
        String PoPackagePath = PACKAGE_PATH + changeFirstChar2UpperCase(lableId) + "Po";
        Class voClazz = Class.forName(VoPackagePath);
        Class poClazz = Class.forName(PoPackagePath);
        //获取vo
        voClazz vo = null;
        try {
            String getterMethods = "get" + changeFirstChar2UpperCase(lableId) + "Vo";
            Method method = (Method) userInfoDialogVo.getClass().getDeclaredMethod(getterMethods);
            method.setAccessible(true);
            vo = (voClazz) method.invoke(userInfoDialogVo);
        }catch (NoSuchMethodException e) {
            e.printStackTrace();
        }catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        //获取po
        poClazz po = (poClazz) QueryCache.get(poClazz,uuid);
        BeanUtils.copyProperties(po,vo);
        //更新po最新变更时间
        Method setLastModifyTimeMethod = (Method) poClazz.getDeclaredMethod("setLastmodifytime",Date.class);
        setLastModifyTimeMethod.setAccessible(true);
        setLastModifyTimeMethod.invoke(po,new Date());
        tx = new TransactionCache();
        tx.update(po);
        tx.commit();
        return tx;
    }

    /**
     * 首字母转大写
     * @param orginStr
     * @return
     */
    public String changeFirstChar2UpperCase(String orginStr){
        String targetStr = "";
        try {
            char[] chararray = orginStr.toCharArray();
            chararray[0] -= 32;
            targetStr = String.valueOf(chararray);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return targetStr;
    }

    /**
     * poname 转 voname
     * @param poName
     * @return
     */
    private String poName2voName(String poName){
        String voName = poName.substring(0,poName.length()-2);
        return  voName;
    }

    /**
     * 记录日志
     */
    public void recordLog(String userId, int optType){
        // 记录日志
        LogPart lp = new LogPart();
        lp.setOpObjType(SUser.class.getName());
        lp.setOpObjId(userId);
        lp.setRelObjType(SUser.class.getName());
        lp.setRelObjId(userId);
        lp.setOpType(optType);
        lp.setLogLevel(LogConstant.LOG_LEVEL_COMMON);
        //lp.setLogData(Json.object2json(item));
        lp.setResult(LogConstant.RESULT_SUCCESS);
        lp.save();
    }

    private SOrg getCorp(String orgId) {
        if (StringHelper.isEmpty(orgId)) {
            return null;
        }
        SOrg parent = QueryCache.get(SOrg.class, orgId);
        if (IdsService.ORG_ORG_TYPE.equals(parent.getOrgType())) {
            return parent;
        } else {
            return getCorp(parent.getParentId());
        }
    }

    /**
     * 解决xwork无法拦截数据的问题
     * @param request
     * @param userInfoPageVo
     */
    public void handleDateparam(HttpServletRequest request , UserInfoPageVo userInfoPageVo){
        try {
            String birthdayParam = request.getParameter("userInfoPageVo.userInfoVo.birthday");
            String joinworktimeParam = request.getParameter("userInfoPageVo.userInfoVo.joinworktime");
            String joinpartytimeParam = request.getParameter("userInfoPageVo.userInfoVo.joinpartytime");
            if(StringHelper.isNotEmpty(birthdayParam)){
                Date birthDay = new SimpleDateFormat("yyyy-MM").parse(birthdayParam);
                userInfoPageVo.getUserInfoVo().setBirthday(birthDay);
            }
            if(StringHelper.isNotEmpty(joinworktimeParam)){
                Date joinworktime = new SimpleDateFormat("yyyy-MM").parse(joinworktimeParam);
                userInfoPageVo.getUserInfoVo().setJoinworktime(joinworktime);
            }
            if(StringHelper.isNotEmpty(joinworktimeParam)){
                Date joinpartytime = new SimpleDateFormat("yyyy-MM").parse(joinpartytimeParam);
                userInfoPageVo.getUserInfoVo().setJoinpartytime(joinpartytime);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 转换成简单排序号  去除机构排序和补齐“0”，只保留用户排序
     * @param orderNum
     * @return
     */
    public static String toSimpleNum(String orderNum){
        return orderNum.replaceAll("\\d*-0*","");
    }

    /**
     * 转化成全量排序号  9999-9999 格式 前四位表示机构编号，后四位表示人员编号 （注意空位需要用0进行补齐）
     * @param orgOrderNum
     * @param userOrderNum
     * @return
     */
    public static String toFullNum(String orgOrderNum,String userOrderNum){
        return fillNum(orgOrderNum) + "-" + fillNum(userOrderNum);
    }

    /**
     * 填充0
     * @param num
     * @return
     */
    private static String fillNum(String num){
        if(num.length()<4){
            int loopNum = 4-num.length();
            for (int i = 0; i < loopNum; i++) {
                num = "0"+num;
            }
        }
        return  num;
    }

    public String getResult() {
        return result;
    }

    public void setResult(String result) {
        this.result = result;
    }

    public String getOperFlag() {
        return operFlag;
    }

    public void setOperFlag(String operFlag) {
        this.operFlag = operFlag;
    }

}
